#include "Transaction.h"

InPoint::InPoint()
    : m_ptx(nullptr)
    , m_num(-1) {}

InPoint::InPoint(Transaction* ptx, unsigned int in)
    : m_ptx(ptx)
    , m_num(in) {}

void InPoint::setNull() {
    m_ptx = nullptr;
    m_num = -1;
}

bool InPoint::isNull() {
    return m_ptx == nullptr && m_num == -1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

OutPoint::OutPoint()
    : m_hash(0)
    , m_num(-1) {}

OutPoint::OutPoint(Uint256 hashIn, unsigned int in)
    : m_hash(hashIn)
    , m_num(in) {}

void OutPoint::setNull() {
    m_hash = nullptr;
    m_num = -1;
}
bool OutPoint::isNull(){
    return m_hash == nullptr && m_num == -1;
}
std::string OutPoint::toString() const {
    return strprintf("COutPoint(%s, %d)", m_hash.ToString().substr(0,6).c_str(), n);
}
void OutPoint::print() const {
    printf("%s\n", toString().c_str());
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

TxIn::TxIn() : m_sequence(UINT32_MAX) {}

TxIn::TxIn(OutPoint prevOutIn, Script scriptSigIn=Script(), unsigned int seq=UINT32_MAX)
    : m_prev_out(prevOutIn)
    , m_script_sig(scriptSigIn)
    , m_sequence(seq){}

TxIn::TxIn(Uint256 hashPrevTx, unsigned int outNum, Script scriptSigIn=Script(), unsigned int seq=UINT32_MAX)
    : m_prev_out(OutPoint(hashPrevTx, outNum))
    , m_script_sig(scriptSigIn)
    , m_sequence(seq) {}

bool TxIn::isFinal() {
    return m_sequence == UINT32_MAX;
}

std::string TxIn::toString() const {
    std::string str;
    str += strprintf("TxIn(");
    str += m_prev_out.toString();
    if (prevout.IsNull()) {
        str += strprintf(", coinbase %s", HexStr(m_script_sig.begin(), m_script_sig.end(), false).c_str());
    } else {
        str += strprintf(", scriptSig=%s", m_script_sig.ToString().substr(0,24).c_str());
    }

    if (m_sequence != UINT_MAX) {
        str += strprintf(", sequence=%u", m_sequence);
    }

    str += ")";
    return str;
}

void TxIn::print() const {
    printf("%s\n", toString().c_str());
}

bool TxIn::isMine() const {
    // TODO: mutex lock
    std::map<Uint256, WalletTx>::iterator mi = mapWallet.find(m_prev_out.m_hash);
    if (mi != mapWallet.end()) {
        const WalletTx& prev = (*mi).second;
        if (m_prev_out < prev.vout.size()) {
            if (prev.vout[m_prev_out.m_num].isMine()) {
                return true;
            }
        }
    }
    return false;
}
int64_t TxIn::getDebit() const {

}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TxOut::TxOut(){

}
TxOut::TxOut(int64_t valueIn, Script scriptPubkeyIn){

}
void TxOut::setNull(){

}
bool TxOut::isNull(){

}
Uint256 TxOut::getHash()const{

}
bool TxOut::isMine(){

}
int64_t TxOut::getCredit()const{

}
std::string TxOut::toString()const{

}
void TxOut::print() const {

}